#include "LogicDone.h"

Display LogicDone::doneByIndex( int index ) {

	string statusMessage;
	int taskID;
	Data::DataFeedback dataFeedback;
	vector<Task> tasks;
	vector<Task> display;
	bool outOfBounds;
	bool isNotMarked;
	bool markState;

	outOfBounds = isOutOfBounds(index, _display.getDisplaySize());

	if( outOfBounds ) {
		throw(INDEX_OUT_OF_BOUNDS_ERROR_MESSAGE);
	}

	display = _display.getTaskList();

	taskID = display[index-1].getTaskID();

	// check done state of a task
	// if done mark undone
	// if undone mark done
	if( display[index-1].getDone() == true ) {
		isNotMarked = false;
		markState = false;
	} else if( display[index-1].getDone() == false ) {
		isNotMarked = true;
		markState = true;
	}

	// set task attributes
	display[index-1].setDone(markState);
	_task = display[index-1];
	
	dataFeedback = _data->executeEdit(_task);

	if( dataFeedback == Data::FAILURE ) {
		throw(DONE_ERROR_MESSAGE);
	}

	if( dataFeedback == Data::SUCCESS ) {
		_data->getAll(tasks);
		_writer->write(tasks);

		if( isNotMarked == true ) {
			statusMessage = DONE_SUCCESS_MESSAGE;
		} else if( isNotMarked == false ) {
			statusMessage = UNDONE_SUCCESS_MESSAGE;
		} else {
			statusMessage = DONE_SUCCESS_MESSAGE;
		}
	}

	_display = Display( statusMessage, display );

	return _display;
}

Display LogicDone::doneBySearchTerm( string searchTerm ) {
	
	string statusMessage;
	int taskID;
	bool multipleMatches;
	Data::DataFeedback dataFeedback;
	vector<Task> tasks;
	vector<Task> display;
	bool isNotMarked;
	bool markState;

	dataFeedback = _data->getBySearchTerm(tasks, searchTerm);

	if( dataFeedback == Data::NOT_FOUND ) {
		throw(NOT_FOUND_ERROR_MESSAGE);
	}
	
	// found 1 match
	if( tasks.size() == FOUND_ONE_MATCH ) {
		_task = tasks[FIRST_POSITION];

		if( _task.getDone() == true ) {
			isNotMarked = false;
			markState = isNotMarked;
		} else {
			isNotMarked = true;
			markState = isNotMarked;
		}

		_task.setDone(markState);
		taskID = _task.getTaskID();
		dataFeedback = _data->executeEdit(_task);
		multipleMatches = false;
	}

	if( dataFeedback == Data::FAILURE ) {
		throw(DONE_ERROR_MESSAGE);
	}

	display = _display.getTaskList();

	if( multipleMatches ) {
		display = tasks;
		statusMessage = DONE_MULTIPLE_MATCH_ERROR_MESSAGE;
	} else {
		_data->getByID(tasks, taskID);
		display = tasks;
		tasks.clear();
		_data->getAll(tasks);
		_writer->write(tasks);

		if( isNotMarked ) {
			statusMessage = DONE_SUCCESS_MESSAGE;
		} else  {
			statusMessage = UNDONE_SUCCESS_MESSAGE;
		}
	}

	_display = Display( statusMessage, display );

	return _display;
}

const string LogicDone::DONE_SUCCESS_MESSAGE = "Marked Done";
const string LogicDone::UNDONE_SUCCESS_MESSAGE = "Marked Un-Done";

const string LogicDone::DONE_ERROR_MESSAGE = "Unable to Mark Done";
const string LogicDone::DONE_MULTIPLE_MATCH_ERROR_MESSAGE = "Multiple Matches Found";

const int LogicDone::FOUND_ONE_MATCH = 1;
const int LogicDone::FIRST_POSITION = 0;